home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / gui / eagui30.lha / EAGUI / Pages.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-01  |  14.3 KB  |  603 lines

  1. /*
  2.  * $RCSfile: Pages.c $
  3.  *
  4.  * $Author: marcel $
  5.  *
  6.  * $Revision: 3.1 $
  7.  *
  8.  * $Date: 1994/12/01 07:03:51 $
  9.  *
  10.  * $Locker: marcel $
  11.  *
  12.  * $State: Exp $
  13.  *
  14.  * Description: This is an advanced example of how to use EAGUI. It can be compiled under
  15.  *     SAS/C 6.51. This example demonstrates how you can create pages. Pages are groups of
  16.  *     gadgets. Only one of these groups (one page) is shown. A cycle gadget is used to
  17.  *     browse through the pages.
  18.  *
  19.  *     Although page groups aren't supported directly in EAGUI, you can create them quite
  20.  *     easily because EAGUI is a very open system.
  21.  *
  22.  * Use a tab size of 5 to read this source! Comments were formatted for a right margin of 95,
  23.  * which matches my overscan and font settings. I hope it is readable for others.
  24.  */
  25.  
  26. /* standard headers */
  27. #include <stdlib.h>
  28. #include <exec/types.h>
  29. #include <graphics/text.h>
  30. #include <intuition/intuition.h>
  31. #include <libraries/gadtools.h>
  32. #include <clib/macros.h>
  33. #include <proto/diskfont.h>
  34. #include <proto/exec.h>
  35. #include <proto/intuition.h>
  36. #include <proto/gadtools.h>
  37. #include <proto/graphics.h>
  38. #include <proto/dos.h>
  39.  
  40. /* EAGUI headers */
  41. #include "EAGUI.h"
  42. #include "EAGUI_pragmas.h"
  43.  
  44. /* custom object(s) */
  45. #include "TextField.c"
  46.  
  47. /* globals */
  48. struct ea_Object *            winobj_ptr        = NULL;
  49. struct ea_Object *            pgroupobj_ptr        = NULL;
  50. struct ea_Object *            page1_ptr            = NULL;
  51. struct ea_Object *            page2_ptr            = NULL;
  52. struct ea_Object *            page3_ptr            = NULL;
  53. struct Window *            win_ptr            = NULL;
  54. struct Screen *            scr_ptr            = NULL;
  55. struct Gadget *            gadlist_ptr        = NULL;
  56. struct Gadget *            cycle_ptr            = NULL;
  57. APTR                     visualinfo_ptr        = NULL;
  58. struct DrawInfo *            drawinfo_ptr        = NULL;
  59. struct TextFont *            tf_ptr            = NULL;
  60. struct Library *            EAGUIBase            = NULL;
  61. struct TextAttr             textattr             = {"helvetica.font", 15, FS_NORMAL, FPB_DISKFONT};
  62. struct ci_TextField            textfield1;
  63. struct Hook                tfminsizehook;
  64. struct Hook                tfrenderhook;
  65. struct Hook                pgminsizehook;
  66. struct IntuiMessage            imsg;
  67. STRPTR                    labels[]            = {
  68.                                             "Page One",
  69.                                             "Page Two",
  70.                                             "Page Three",
  71.                                             NULL};
  72. #define page                 (cytaglist1[1].ti_Data)
  73. struct TagItem                cytaglist1[]        = {
  74.                                             {GTCY_Labels,            (LONG)labels},
  75.                                             {GTCY_Active,            0},
  76.                                             {TAG_DONE}};
  77. STATIC UBYTE                rcs_id_string[]    = "$Id: Pages.c 3.1 1994/12/01 07:03:51 marcel Exp marcel $";
  78.  
  79. /* constants */
  80. #define LAYOUTSPACING        4
  81. #define CYCLEGADGET_ID        666
  82.  
  83. /* prototypes */
  84. ULONG __saveds __asm        HookEntry(register __a0 struct Hook *, register __a2 VOID *, register __a1 VOID *);
  85. VOID                        InitHook(struct Hook *, ULONG (*)(), VOID *);
  86. ULONG                    meth_minsize_pgroup(struct Hook *, struct ea_Object *, APTR);
  87. LONG                        init(VOID);
  88. VOID                        cleanup(STRPTR);
  89. VOID                        resizewindow(VOID);
  90. VOID                        repagewindow(VOID);
  91. ULONG                    handlemsgs(VOID);
  92.  
  93. /* functions for hook handling */
  94. ULONG __saveds __asm HookEntry
  95. (
  96.     register __a0 struct Hook *    hook_ptr,
  97.     register __a2 VOID *        object_ptr,
  98.     register __a1 VOID *        message_ptr
  99. )
  100. {
  101.     return((*hook_ptr->h_SubEntry)(hook_ptr, object_ptr, message_ptr));
  102. }
  103.  
  104. VOID InitHook(struct Hook *h_ptr, ULONG (*func_ptr)(), VOID *data_ptr)
  105. {
  106.     if (h_ptr)
  107.     {
  108.         h_ptr->h_Entry = (ULONG (*)())HookEntry;
  109.         h_ptr->h_SubEntry = func_ptr;
  110.         h_ptr->h_Data = data_ptr;
  111.     }
  112. }
  113.  
  114. /* page group minsize method */
  115. ULONG meth_minsize_pgroup(struct Hook *hook_ptr, struct ea_Object *obj_ptr, APTR msg_ptr)
  116. {
  117.     struct ea_Object *    current_ptr;
  118.     LONG                minwidth;
  119.     LONG                minheight;
  120.     LONG                w, h;
  121.     LONG                mw, mh, bl, br, bt, bb;
  122.     struct TagItem        msg_taglist[] = {
  123.         {EA_MinWidth,        0L},
  124.         {EA_MinHeight,        0L},
  125.         {EA_BorderLeft,    0L},
  126.         {EA_BorderRight,    0L},
  127.         {EA_BorderTop,        0L},
  128.         {EA_BorderBottom,    0L},
  129.         {EA_NextObject,    0L},
  130.         {TAG_DONE,        0L}
  131.         };
  132.  
  133.     /* starting values */
  134.     minwidth                = 0;
  135.     minheight                = 0;
  136.     current_ptr            = (struct ea_Object *)ea_GetAttr(obj_ptr, EA_FirstChild);
  137.     msg_taglist[0].ti_Data    = (ULONG)&mw;
  138.     msg_taglist[1].ti_Data    = (ULONG)&mh;
  139.     msg_taglist[2].ti_Data    = (ULONG)&bl;
  140.     msg_taglist[3].ti_Data    = (ULONG)&br;
  141.     msg_taglist[4].ti_Data    = (ULONG)&bt;
  142.     msg_taglist[5].ti_Data    = (ULONG)&bb;
  143.     msg_taglist[6].ti_Data    = (ULONG)¤t_ptr;
  144.  
  145.     /* do all children */
  146.     while (current_ptr)
  147.     {
  148.         /* get the required attributes */
  149.         ea_GetAttrsA(current_ptr, msg_taglist);
  150.  
  151.         /* determine the minimum dimensions of this child */
  152.         w = mw + bl + br;
  153.         h = mh + bt + bb;
  154.  
  155.         /* check and use these dimensions if they were larger than the largest upto now */
  156.         if (h > minheight)
  157.         {
  158.             minheight = h;
  159.         }
  160.         if (w > minwidth)
  161.         {
  162.             minwidth = w;
  163.         }
  164.     }
  165.  
  166.     /* set the minimum dimensions of the object */
  167.     ea_SetAttr(obj_ptr, EA_MinWidth,    minwidth);
  168.     ea_SetAttr(obj_ptr, EA_MinHeight,    minheight);
  169.  
  170.     /* return zero for success */
  171.     return(0);
  172. }
  173.  
  174. /* initialize everything */
  175. LONG init(VOID)
  176. {
  177.     LONG w, h, bl, br, bt, bb;
  178.  
  179.     /* open the EAGUI library */
  180.     if (!(EAGUIBase = OpenLibrary(EAGUILIBRARYNAME, EAGUILIBRARYVERSION)))
  181.     {
  182.         cleanup("Couldn't open EAGUI.library.\n");
  183.     }
  184.  
  185.     /* open the font */
  186.     if (!(tf_ptr = OpenDiskFont(&textattr)))
  187.     {
  188.         cleanup("Couldn't open font.\n");
  189.     }
  190.  
  191.     /* initialize the pagegroup minsize hook */
  192.     InitHook(&pgminsizehook, meth_minsize_pgroup, NULL);
  193.  
  194.     /* initialize textfield hooks */
  195.     InitHook(&tfminsizehook, meth_MinSize_TextField, NULL);
  196.     InitHook(&tfrenderhook, meth_Render_TextField, NULL);
  197.  
  198.     /* set up some defaults for all objects */
  199.     ea_SetAttr(NULL, EA_DefGTTextAttr, (ULONG)&textattr);
  200.  
  201.     /* now we can build the object tree */
  202.     if (!(winobj_ptr = HGroup
  203.         EA_BorderLeft,        LAYOUTSPACING,
  204.         EA_BorderRight,    LAYOUTSPACING,
  205.         EA_BorderTop,        LAYOUTSPACING,
  206.         EA_BorderBottom,    LAYOUTSPACING,
  207.         EA_Child,            VGroup
  208.             EA_Weight,        1,
  209.             EA_BorderRight,    LAYOUTSPACING,
  210.             EA_Child,            EmptyBox(1)
  211.                 End,
  212.             EA_Child,            GTButton("Help...")
  213.                 End,
  214.             EA_Child,            EmptyBox(1)
  215.                 End,
  216.             EA_Child,            GTButton("Ok")
  217.                 End,
  218.             EA_Child,            GTButton("Cancel")
  219.                 End,
  220.             End,
  221.         EA_Child,            VGroup
  222.             EA_Weight,        2,
  223.             EA_Child,            GTCycle
  224.                 EA_GTTagList,        cytaglist1,
  225.                 EA_InstanceAddress,    &cycle_ptr,
  226.                 EA_ID,            CYCLEGADGET_ID,
  227.                 End,
  228.             EA_Child,            pgroupobj_ptr = ea_NewObject(EA_TYPE_HGROUP,
  229.                 EA_StandardMethod,    EASM_BORDER,
  230.                 EA_Weight,        1,
  231.                 EA_MinSizeMethod,    &pgminsizehook,
  232.                 EA_Child,            page1_ptr = GTListView(NULL)
  233.                     EA_Weight,        1,
  234.                     End,
  235.                 EA_Child,            page2_ptr = VGroup
  236.                     EA_Weight,        1,
  237.                     EA_Child,            EmptyBox(2)
  238.                         End,
  239.                     EA_Child,            GTString("Username:")
  240.                         End,
  241.                     EA_Child,            EmptyBox(1)
  242.                         End,
  243.                     EA_Child,            GTString("Password:")
  244.                         End,
  245.                     EA_Child,            EmptyBox(2)
  246.                         End,
  247.                     End,
  248.                 EA_Child,            page3_ptr = ea_NewObject(EA_TYPE_CUSTOMIMAGE,
  249.                     EA_Weight,        1,
  250.                     EA_BorderBottom,    4,
  251.                     EA_MinSizeMethod,    &tfminsizehook,
  252.                     EA_RenderMethod,    &tfrenderhook,
  253.                     EA_UserData,        &textfield1,
  254.                     TAG_DONE),
  255.                 TAG_DONE),
  256.             End,
  257.         End))
  258.     {
  259.         cleanup("Couldn't init the objects.\n");
  260.     }
  261.  
  262.     /* lock the screen */
  263.     if (!(scr_ptr = LockPubScreen(NULL)))
  264.     {
  265.         cleanup("Couldn't lock default public screen.\n");
  266.     }
  267.  
  268.     /* get VisualInfo and DrawInfo */
  269.     if (!(visualinfo_ptr = GetVisualInfo(scr_ptr, TAG_DONE)))
  270.     {
  271.         cleanup("Couldn't get the visual info.\n");
  272.     }
  273.     if (!(drawinfo_ptr = GetScreenDrawInfo(scr_ptr)))
  274.     {
  275.         cleanup("Couldn't get the draw info.\n");
  276.     }
  277.  
  278.     /* fill in the textfield structure */
  279.     textfield1.tf_string_ptr        = "Connection Established";    /* title */
  280.     textfield1.tf_textattr_ptr    = &textattr;                /* font */
  281.     textfield1.tf_flags            = 0;                        /* alignment flags */
  282.     textfield1.tf_frontpen        = 2;                        /* frontpen color index */
  283.  
  284.      /* obtain the minimum dimensions of every object in the tree */
  285.      ea_GetMinSizes(winobj_ptr);
  286.  
  287.     /* enable and disable the right pages */
  288.     ea_SetAttr(page1_ptr, EA_Disabled, (page == 0) ? FALSE : TRUE);
  289.     ea_SetAttr(page2_ptr, EA_Disabled, (page == 1) ? FALSE : TRUE);
  290.     ea_SetAttr(page3_ptr, EA_Disabled, (page == 2) ? FALSE : TRUE);
  291.  
  292.     /* get some attributes */
  293.     ea_GetAttrs(winobj_ptr,
  294.         EA_MinWidth,        &w,
  295.         EA_MinHeight,        &h,
  296.         EA_BorderLeft,        &bl,
  297.         EA_BorderRight,    &br,
  298.         EA_BorderTop,        &bt,
  299.         EA_BorderBottom,    &bb,
  300.         TAG_DONE);
  301.  
  302.      /* open the window */
  303.      if (!(win_ptr = OpenWindowTags(NULL,
  304.          WA_Title,            "EAGUI Pages Example",
  305.         WA_Flags,            (WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM | WFLG_ACTIVATE),
  306.         WA_IDCMP,            (IDCMP_CLOSEWINDOW | BUTTONIDCMP | STRINGIDCMP | IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE),
  307.         WA_InnerHeight,    (h + bt + bb) * 2,
  308.         WA_InnerWidth,        (w + bl + br) * 2,
  309.         TAG_DONE)))
  310.     {
  311.         cleanup("Couldn't open the window.\n");
  312.     }
  313.  
  314.     /* set the window limits */
  315.     WindowLimits(
  316.         win_ptr,
  317.         w + win_ptr->BorderLeft + win_ptr->BorderRight + bl + br,
  318.         h + win_ptr->BorderTop + win_ptr->BorderBottom + bt + bb,
  319.         ~0,
  320.         ~0);
  321.  
  322.     /* create the gadgets and add them to the window */
  323.     resizewindow();
  324.  
  325.     return(0);
  326. }
  327.  
  328. /* clean up everything that was created */
  329. VOID cleanup(STRPTR str_ptr)
  330. {
  331.     int rc = 0;
  332.  
  333.     /* if a string is passed, we assume there was some kind of error */
  334.     if (str_ptr)
  335.     {
  336.         Printf("Error: %s", str_ptr);
  337.         rc = 20;
  338.     }
  339.  
  340.     if (gadlist_ptr)
  341.     {
  342.         RemoveGList(win_ptr, gadlist_ptr, -1);
  343.         ea_FreeGadgetList(winobj_ptr, gadlist_ptr);
  344.         gadlist_ptr = NULL;
  345.     }
  346.  
  347.     if (win_ptr)
  348.     {
  349.         CloseWindow(win_ptr);
  350.         win_ptr = NULL;
  351.     }
  352.  
  353.     if (drawinfo_ptr)
  354.     {
  355.         FreeScreenDrawInfo(scr_ptr, drawinfo_ptr);
  356.         drawinfo_ptr = NULL;
  357.     }
  358.  
  359.     if (visualinfo_ptr)
  360.     {
  361.         FreeVisualInfo(visualinfo_ptr);
  362.         visualinfo_ptr = NULL;
  363.     }
  364.  
  365.     if (scr_ptr)
  366.     {
  367.         UnlockPubScreen(NULL, scr_ptr);
  368.         scr_ptr = NULL;
  369.     }
  370.  
  371.     if (winobj_ptr)
  372.     {
  373.         ea_DisposeObject(winobj_ptr);
  374.         winobj_ptr = NULL;
  375.     }
  376.  
  377.     if (tf_ptr)
  378.     {
  379.         CloseFont(tf_ptr);
  380.         tf_ptr = NULL;
  381.     }
  382.  
  383.     if (EAGUIBase)
  384.     {
  385.         CloseLibrary(EAGUIBase);
  386.         EAGUIBase = NULL;
  387.     }
  388.  
  389.     exit(rc);
  390. }
  391.  
  392. /* (re)create the gadget list after a size change */
  393. VOID resizewindow(VOID)
  394. {
  395.     LONG bl, br, bt, bb;
  396.  
  397.     /* if necessary, remove the gadget list from the window, and clean it up */
  398.     if (gadlist_ptr)
  399.     {
  400.         RemoveGList(win_ptr, gadlist_ptr, -1);
  401.         ea_FreeGadgetList(winobj_ptr, gadlist_ptr);
  402.         gadlist_ptr = NULL;
  403.     }
  404.  
  405.     ea_GetAttrs(winobj_ptr,
  406.         EA_BorderLeft,        &bl,
  407.         EA_BorderRight,    &br,
  408.         EA_BorderTop,        &bt,
  409.         EA_BorderBottom,    &bb,
  410.         TAG_DONE);
  411.  
  412.      ea_SetAttrs(winobj_ptr,
  413.         EA_Width,        win_ptr->Width -
  414.                     win_ptr->BorderLeft -
  415.                     win_ptr->BorderRight -
  416.                     bl -
  417.                     br,
  418.         EA_Height,    win_ptr->Height -
  419.                     win_ptr->BorderTop -
  420.                     win_ptr->BorderBottom -
  421.                     bt -
  422.                     bb,
  423.         EA_Left,        win_ptr->BorderLeft,
  424.         EA_Top,        win_ptr->BorderTop,
  425.         TAG_DONE);
  426.  
  427.     ea_LayoutObjects(winobj_ptr);
  428.  
  429.     if (ea_CreateGadgetList(winobj_ptr, &gadlist_ptr, visualinfo_ptr, drawinfo_ptr) != EA_ERROR_OK)
  430.     {     
  431.         cleanup("Couldn't create the gadget list.\n");
  432.     }     
  433.  
  434.     EraseRect(win_ptr->RPort,     
  435.         win_ptr->BorderLeft,
  436.         win_ptr->BorderTop,
  437.         win_ptr->Width - win_ptr->BorderRight - 1,
  438.         win_ptr->Height - win_ptr->BorderBottom - 1);
  439.  
  440.     RefreshWindowFrame(win_ptr);
  441.  
  442.     AddGList(win_ptr, gadlist_ptr, -1, -1, NULL);
  443.     RefreshGList(gadlist_ptr, win_ptr, NULL, -1);
  444.     GT_RefreshWindow(win_ptr, NULL);
  445.  
  446.     /* finally, we render the imagery, if there is any */
  447.     ea_RenderObjects(winobj_ptr, win_ptr->RPort);
  448. }
  449.  
  450. /* (re)create the gadget list after a page change */
  451. VOID repagewindow(VOID)
  452. {
  453.     LONG bl, br, bt, bb;
  454.     LONG gw, gh, gt, gl;
  455.  
  456.     /* if necessary, remove the gadget list from the window, and clean it up */
  457.     if (gadlist_ptr)
  458.     {
  459.         RemoveGList(win_ptr, gadlist_ptr, -1);
  460.         ea_FreeGadgetList(winobj_ptr, gadlist_ptr);
  461.         gadlist_ptr = NULL;
  462.     }
  463.  
  464.     ea_GetAttrs(winobj_ptr,
  465.         EA_BorderLeft,        &bl,
  466.         EA_BorderRight,    &br,
  467.         EA_BorderTop,        &bt,
  468.         EA_BorderBottom,    &bb,
  469.         TAG_DONE);
  470.  
  471.      ea_SetAttrs(winobj_ptr,
  472.         EA_Width,        win_ptr->Width -
  473.                     win_ptr->BorderLeft -
  474.                     win_ptr->BorderRight -
  475.                     bl -
  476.                     br,
  477.         EA_Height,    win_ptr->Height -
  478.                     win_ptr->BorderTop -
  479.                     win_ptr->BorderBottom -
  480.                     bt -
  481.                     bb,
  482.         EA_Left,        win_ptr->BorderLeft,
  483.         EA_Top,        win_ptr->BorderTop,
  484.         TAG_DONE);
  485.  
  486.     ea_LayoutObjects(winobj_ptr);
  487.  
  488.     if (ea_CreateGadgetList(winobj_ptr, &gadlist_ptr, visualinfo_ptr, drawinfo_ptr) != EA_ERROR_OK)
  489.     {     
  490.         cleanup("Couldn't create the gadget list.\n");
  491.     }     
  492.  
  493.     /* now determine the exact position of the page in the window */
  494.     gl = ea_GetObjectLeft(winobj_ptr, pgroupobj_ptr);
  495.     gt = ea_GetObjectTop(winobj_ptr, pgroupobj_ptr);
  496.     gw = ea_GetAttr(pgroupobj_ptr, EA_Width);
  497.     gh = ea_GetAttr(pgroupobj_ptr, EA_Height);
  498.  
  499.     /* clear only the page instead of the complete window */
  500.     EraseRect(win_ptr->RPort,
  501.         gl,
  502.         gt,
  503.         gl + gw - 1,
  504.         gt + gh - 1);
  505.  
  506.     AddGList(win_ptr, gadlist_ptr, -1, -1, NULL);
  507.     RefreshGList(gadlist_ptr, win_ptr, NULL, -1);
  508.     GT_RefreshWindow(win_ptr, NULL);
  509.  
  510.     /* finally, we render the imagery, if there is any */
  511.     ea_RenderObjects(winobj_ptr, win_ptr->RPort);
  512. }
  513.  
  514. /* a normal message handling loop */
  515. ULONG handlemsgs(VOID)
  516. {
  517.     struct IntuiMessage    *    imsg_ptr;
  518.     ULONG                rc = 0;
  519.  
  520.     while (imsg_ptr = GT_GetIMsg(win_ptr->UserPort))
  521.     {
  522.         CopyMem((char *)imsg_ptr, (char *)&imsg, (long)sizeof(struct IntuiMessage));
  523.  
  524.         GT_ReplyIMsg(imsg_ptr);
  525.  
  526.         switch (imsg.Class)
  527.         {
  528.             case    IDCMP_REFRESHWINDOW:
  529.                 /* just do the normal refreshing here */
  530.                 GT_BeginRefresh(win_ptr);
  531.                 GT_EndRefresh(win_ptr, TRUE);
  532.                 break;
  533.  
  534.             case    IDCMP_CLOSEWINDOW:
  535.                 /* set the return code */
  536.                 rc = 10;
  537.                 break;
  538.  
  539.             case    IDCMP_NEWSIZE:
  540.                 /* resize the window */
  541.                 resizewindow();
  542.                 break;
  543.  
  544.             case IDCMP_GADGETUP:
  545.                 /* check if the user clicked on the cycle gadget */
  546.                 if ((((struct Gadget *)imsg.IAddress)->GadgetID) == CYCLEGADGET_ID)
  547.                 {
  548.                     /* the user clicked on the cycle gadget and selected a different page */
  549.                     page = imsg.Code;
  550.  
  551.                     /* enable and disable the right pages */
  552.                     ea_SetAttr(page1_ptr, EA_Disabled, (page == 0) ? FALSE : TRUE);
  553.                     ea_SetAttr(page2_ptr, EA_Disabled, (page == 1) ? FALSE : TRUE);
  554.                     ea_SetAttr(page3_ptr, EA_Disabled, (page == 2) ? FALSE : TRUE);
  555.  
  556.                     /* refresh the window and the gadgets */
  557.                     repagewindow();
  558.                 }
  559.                 break;
  560.         }
  561.     }
  562.     return(rc);
  563. }
  564.  
  565. /* main */
  566. int main(int argc, char *argv[])
  567. {
  568.     ULONG idcmpmask, signals;
  569.     BOOL done = FALSE;
  570.  
  571.     /* process any startup options the user has supplied */
  572.     if (argc > 1)
  573.     {
  574.         /* first argument is the font name */
  575.         textattr.ta_Name = argv[1];
  576.         if (argc > 2)
  577.         {
  578.             /* second argument is the font y-size */
  579.             textattr.ta_YSize = atoi(argv[2]);
  580.         }
  581.     }
  582.  
  583.     /* initialize everything */
  584.     init();
  585.  
  586.     /* event handling loop */
  587.     idcmpmask = 1L << win_ptr->UserPort->mp_SigBit;
  588.     while (done == FALSE)
  589.     {
  590.         signals = Wait(idcmpmask);
  591.         if (signals & idcmpmask)
  592.         {
  593.             if (handlemsgs() != 0)
  594.             {
  595.                 done = TRUE;
  596.             }
  597.         }
  598.     }
  599.  
  600.     /* cleanup everything */
  601.     cleanup(NULL);
  602. }
  603.